package integration.util;

import integration.dom.Message;
import integration.properties.compression.CompressionFactory;
import integration.properties.compression.CompressionType;
import integration.properties.compression.impl.AbstractCompressionType;
import integration.properties.compression.impl.BZCompressionTypeImpl;
import integration.properties.compression.impl.L4zCompressionTypeImpl;
import integration.properties.compression.impl.ZCompressionTypeImpl;
import integration.properties.message.MessageFormat;
import integration.properties.message.MessageFormatFactory;
import integration.properties.message.impl.CsvMessageFormatImpl;
import integration.properties.message.impl.JsonMessageFormatImpl;
import integration.properties.message.impl.XmlMessageFormatImpl;

import java.util.Arrays;
import java.util.List;

public class MessageUtil {

    private static List<AbstractCompressionType> compressionTypeList = Arrays.asList(
            new BZCompressionTypeImpl(),
            new ZCompressionTypeImpl(),
            new L4zCompressionTypeImpl()
    );


    private static List<? extends MessageFormat> messageFormatList = Arrays.asList(
            new XmlMessageFormatImpl(),
            new CsvMessageFormatImpl(),
            new JsonMessageFormatImpl()
    );


    public static Message uncompress(Message message) {
        if (!message.isCompressed())
            throw new IllegalArgumentException("Invalid argument, only compressed messages can be uncompressed: " + message);

        for (CompressionType compressionType : compressionTypeList) {
            if (compressionType.isSameCompressionTypeOf(message)) return compressionType.uncompress(message);
        }
        throw new IllegalArgumentException("Message compression type is not recognized: " + message);
    }

    public static Message compress(Message message, String requestedCompression) {
        CompressionType compressionType = CompressionFactory.createCompressionType(requestedCompression);
        return compressionType.compress(message);
    }

    public static Message unformat(Message message, String requestedFormat) {
        for (MessageFormat messageFormat : messageFormatList) {
            if (messageFormat.isSameFormatOf(message)) {
                if (messageFormat.toString().equalsIgnoreCase(requestedFormat)) { // if the message is already in the correct format
                    message.setMessageFormat(messageFormat.toString());
                    return message;
                }
                return messageFormat.unformat(message);
            }
        }
        throw new IllegalArgumentException("File format on received message could not be found: " + message);
    }

    public static Message format(Message uncompressedMessage, String requestedFormat) {
        Message unformattedMessage = unformat(uncompressedMessage, requestedFormat);
        if (unformattedMessage.getMessageFormat() != null)
            return uncompressedMessage; // message is already in the correct format
        MessageFormat messageFormat = MessageFormatFactory.createMessageFormat(requestedFormat);
        return messageFormat.format(uncompressedMessage);
    }
}
